/**
 * This blog post recommended using nsITraceableChannel to intercept requests so
 * that their content could be rewritten:
 *
 * http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/
 */
// goog.provide('jsbloat');
var jsbloat = jsbloat || {};


/** @type {string} */
jsbloat.HTTP_ON_MODIFY_REQUEST = 'http-on-modify-request';


/** @type {string} */
jsbloat.HTTP_ON_EXAMINE_RESPONSE = 'http-on-examine-response';


/** @type {string} */
jsbloat.HTTP_ON_EXAMINE_CACHED_RESPONSE =
    'http-on-examine-cached-response';


/** @return {StreamIgnorer} */
jsbloat.createStreamIgnorer = function() {
  return Components.classes['@jsbloat.googlecode.com/StreamIgnorer/;1'].
      createInstance(Components.interfaces.nsISupports).
      wrappedJSObject;
};


/**
 * Static instance so its getInstrumentedFileForUrl() method is available.
 * (This logic should probably be exposed via an XPCOM service instead.)
 * @type {StreamIgnorer}
 */
jsbloat.streamIgnorer = jsbloat.createStreamIgnorer();


/**
 * @param {nsISupports} subject In practice, this is an nsIHttpChannel.
 * @param {string} topic
 * @param {?string} data In practice, this always seems to be null.
 */
jsbloat.observe = function(subject, topic, data) {
  subject.QueryInterface(Components.interfaces.nsIHttpChannel);

  if (topic == jsbloat.HTTP_ON_EXAMINE_RESPONSE ||
      topic == jsbloat.HTTP_ON_EXAMINE_CACHED_RESPONSE) {
    var uri = subject.URI;
    var url = uri.spec;

    // If the request should return an instrumented file, then override the
    // nsIStreamListener.
    if (jsbloat.streamIgnorer.getInstrumentedFileForUrl(url)) {
      subject.QueryInterface(Components.interfaces.nsITraceableChannel);
      var streamListener = jsbloat.createStreamIgnorer();
      streamListener.listener = subject.setNewListener(streamListener);
    }
  }
};


/** @type {boolean} */
jsbloat.isInitialized = false;


/** Does the one-time initialization for the JSBloat extension. */
jsbloat.init = function() {
  if (jsbloat.isInitialized) return;

  var observerService = Components.classes["@mozilla.org/observer-service;1"].
      getService(Components.interfaces.nsIObserverService);
  observerService.addObserver(jsbloat, jsbloat.HTTP_ON_MODIFY_REQUEST, false);
  observerService.addObserver(jsbloat, jsbloat.HTTP_ON_EXAMINE_RESPONSE, false);
  observerService.addObserver(jsbloat, jsbloat.HTTP_ON_EXAMINE_CACHED_RESPONSE, false);

  jsbloat.isInitialized = true;
};


jsbloat.init();
